Function.RegisterNamespace("System.Script");

System.Script.ObjectSerializer=function(){
    var _safeRegex=/^\(?("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?\)?$/;
    
    this.Deserialize=function(source){
        var target=null;
        if(source){
            if(!_safeRegex.test(source))throw new Error(String.Format("System.Script.ObjectSerializer.Deserialize: 'source' is invalid or unsafe object notation.\nSource: {0}",source));
            try{
                target=eval(['(',')'].join(source));
                target.toString=Function.GetDelegate(overrideToString,this,source);
            }catch(e){
                throw new Error(String.Format("System.Script.ObjectSerializer.Deserialize: unable to deserialize source.\nError: {0}.\nSource: {1}",e,source));
            };
        }
        return target;
    };

    this.Serialize=function(target){
        if(target==null)return "null";
        if(target instanceof Array){
            var ret=[];
            for(var i=0;i<target.length;i++)ret.push(this.Serialize(target[i]));
            return String.Format("[{0}]",ret.join(','));
        }
        if(Object.IsType(Date,target)){
            return String.Format("\"{0}/{1}/{2}T{3}:{4}:{5}Z\"",target.getUTCFullYear(),pad(1+target.getUTCMonth()),pad(target.getUTCDate()),pad(target.getUTCHours()),pad(target.getUTCMinutes()),pad(target.getUTCSeconds()));
        }
        if(typeof(target)=="object"){
            var ret=[];
            for(var x in target)ret.push(String.Format("{0}:{1}",this.Serialize(x),this.Serialize(target[x])));
            return String.Format("{{0}}",ret.join(','));
        }
        if(typeof(target)=="string")return String.Format("\"{0}\"",target.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r"));
        if(!(typeof(target)==="function"))return target.toString();
        return "\"\"";
    };
    
    function overrideToString(source){
        return source;
    }
    
    function pad(number){
        return String.Pad(number,'0',2);
    }
};